package main

import "fmt"

type MyLock struct {
	// you should have a channel here
	ch chan struct{}
}

func NewMutex() *MyLock {
	mu := &MyLock{make(chan struct{}, 1)}
	mu.ch <- struct{}{}
	return mu
}

func (m *MyLock) Lock() {
	<-m.ch
}

func (m *MyLock) Unlock() {
	select {
	case m.ch <- struct{}{}:
	default:
		panic("unlock of unlocked mutex")
	}
}

func (m *MyLock) TryLock() bool {
	select {
	case <-m.ch:
		return true
	default:
	}
	return false
}

func main() {
	m := MyLock{}
	ok := m.TryLock()
	fmt.Printf("locked v %v \n", ok)
	ok = m.TryLock()
	fmt.Printf("locked v %v \n", ok)
}
